package org.qloudgen.borg.utils;

import java.io.File;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

import org.apache.commons.lang.StringUtils;

/*
 * Validation
 *
 * Copyright (C) 2013 NTT Software Corporation.
 */

/*
 * Check argument without using linux shell command.
 */

public class Validation {

    /*
     * argIsEmpty
     * Check arg is empty.
     */

    public static boolean argIsEmpty(final String arg) {
        if ("".equals(arg) || arg.matches("\\s+")) {
            return true;
        }
        return false;
    }

    /*
     * directoryPathIsValid
     * Check directory starts "/".
     */

    public static boolean directoryPathIsValid(final String directory) {
        if (directory.indexOf("/") == 0) {
            return true;
        }
        return false;
    }

    /*
     * directoryExist
     * Check directory exists.
     */

    public static boolean directoryExist(final String directory) {
        File file = new File(directory);
        return file.exists();
    }

    /*
     * succeedsPing
     * Check ping to address.
     */

    public static boolean succeedsPing(final String address) {
    	if (address == null) return true;
    	boolean result = false;
        try {
            result = InetAddress.getByName(address).isReachable(5000);
        } catch (Exception e) { }
        return result;
    }

    /*
     * portIsValid
     * Check port consists of number
     * and port range is valid.
     */

    public static boolean portIsValid(final String port) {
    	if (port == null) return true;
        if (!port.matches("[0-9]+")) {
            return false;
        } else if (Integer.parseInt(port) < 1024
                || 65535 < Integer.parseInt(port)) {
            return false;
        }
        return true;
    }


    /*
     * postgresqlConfExist
     * Check postgresql_conf exists.
     */

    public static boolean postgresqlConfExist(final String postgresql_conf) {
        File file = new File(postgresql_conf);
        return (file.exists() && file.isFile());
    }
    
    /*
     * check ip 
     */
    public static boolean ipIsValid(final String ip) {
    	if (ip == null) return true;
        if (!ip.matches("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$")) {
            return false;
        }
        return true;
    }

	public static boolean pgHbaIsValid(String pgHba) {
		if (pgHba == null) return true;
		if (!pgHba.matches("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\/([1-3][0-9])$")) {
            return false;
        }
		return true;
	}
	
	public static String getLocalIp() {
		
		Enumeration<NetworkInterface> allNetInterfaces;
		try {
			allNetInterfaces = NetworkInterface.getNetworkInterfaces();
		} catch (SocketException e) {
			e.printStackTrace();
			return null;
		}
		
		InetAddress ip = null;
		String localIp = null;
		while (allNetInterfaces.hasMoreElements()){
			NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
			Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
		
			while (addresses.hasMoreElements()) {
				ip = (InetAddress) addresses.nextElement();
				if (ip != null && ip instanceof Inet4Address && !ip.getHostAddress().equals("127.0.0.1")){
					localIp = ip.getHostAddress();
				} 
			}
		}

		return localIp;
	}

	public static boolean isDigit(String str){
		
		return str.matches("\\d+");
	}

	/*
	 * 检查str如果包含separator，则确保两边都有值，如果isDigit是true，表示还要检验两边值是否都是数字
	 */
	public static boolean check1(String str,String separator,boolean isDigit) {
		
		if (StringUtils.isBlank(str) || StringUtils.isBlank(separator)) return false;
		
		if (StringUtils.countMatches(str, separator) > 1) return false;
		
		if (str.contains(separator)) {
			
			String[] splits = StringUtils.splitByWholeSeparator(str, separator);
			
			for (int i=0; i<splits.length; i++){
				if (StringUtils.isBlank(splits[i])) return false;
				
				if (isDigit && !Validation.isDigit(splits[i])) return false;
			}
			
		} else {
			if (isDigit && !Validation.isDigit(str)) return false;
		}
		
		return true;
	}
}